package com.foreveross.service;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.foreveross.SYWebService.SYHttpclientCall;
import com.foreveross.SYWebService.vo.ConditionVo;
import com.foreveross.SYWebService.vo.DataVo;
import com.foreveross.SYWebService.vo.PaymentVo;
import com.foreveross.SYWebService.vo.SYResult;
import com.foreveross.SYWebService.vo.SYSWin;
import com.foreveross.common.Constants;
import com.foreveross.common.Exception.ExceptionConstant;
import com.foreveross.dao.HouseUserDAO;
import com.foreveross.dao.TenementCostDAO;
import com.foreveross.dao.TenementDAO;
import com.foreveross.util.DateUtil;
import com.foreveross.util.ObjectToMap;
import com.foreveross.util.StringUtil;
import com.foreveross.vo.HouseUser;
import com.foreveross.vo.HrCode;
import com.foreveross.vo.OrderInfo;
import com.foreveross.vo.ProductType;
import com.foreveross.vo.Tenement;
import com.foreveross.vo.TenementCost;
import com.foreveross.vo.common.ResultVo;
import com.foreveross.weixin.service.PayUnifiedOrderService;
import com.foreveross.weixin.vo.pay.PayOrderQueryResult;
import com.foreveross.weixin.vo.pay.PayRequestVo;

@Service("tenementCostService")
@Transactional
public class TenementCostService extends BaseService {

	@Resource
	TenementCostDAO tenementCostDAO;
	@Resource
	HouseUserDAO houseUserDAO;
	@Resource
	TenementDAO tenementDAO;

	public long getTenementCostListCount(String weixinID,String userId, String houseId,
			String IpItemName, String status,String resCode,String type) throws Exception {
		return tenementCostDAO.findTenementCostListCount(weixinID, userId, houseId, IpItemName, status,resCode,type);
	}

	public List<TenementCost> findTenementCostList(String weixinID,String userId, String houseId,
			String IpItemName, String status,String resCode,String type, int pageIndex,
			int pageSize) throws Exception {
		return tenementCostDAO.findTenementCostList(weixinID, userId, houseId, IpItemName, status,resCode,type, pageIndex, pageSize);
	}

	// 得到当前用户的费用列表信息
	public List<DataVo> synUserRev_GetFeeList(String cusID, String startTime,
			String endTime, String orgId) throws Exception {
		ConditionVo conditionVo = new ConditionVo();
		conditionVo.setP0("UserRev_GetFeeList");
		conditionVo.setP1(cusID);
		conditionVo.setP2(startTime);
		conditionVo.setP3(endTime);
		conditionVo.setP4(orgId);
		List<DataVo> dataList = new ArrayList<DataVo>();
		Map<String, String> params = new HashMap<String, String>();

		params = ObjectToMap.objectToMapViaFields(conditionVo, true);
		SYResult sysResult = SYHttpclientCall.getSYData(params);
		List<SYSWin> list = sysResult.getUserRev_GetFeeList();
		if (list != null && !list.isEmpty()) {
			SYSWin sYSWin = list.get(0);
			List<DataVo> dataVoList = sYSWin.getSyswin();
			for (DataVo dataVo : dataVoList) {
				// 9表示已经缴费
				if (!dataVo.getLockLogo().equals("9")) {
					dataVo.getCost();
					List<HouseUser> houseUserList = houseUserDAO
							.getHouseUserByCusIdAndResId(conditionVo.getP1(),
									dataVo.getResID());
					if (houseUserList != null && houseUserList.size() > 0) {
						HouseUser houseUser = houseUserList.get(0);
						dataVo.setHouseUser(houseUser);
						List<Tenement> tenementList = tenementDAO
								.findTenementList(houseUser.getHouseId(), null,
										null, 0, Constants.PAGE_MAX_SIZE, null);
						dataVo.setTenement(tenementList.get(0));
					}

					dataList.add(dataVo);
				}
			}
		}

		return dataList;
	}

	public DataVo synUserRev_GetFee(String cusID, String orgId, String revID)
			throws Exception {
		DataVo data = null;
		List<DataVo> dataVoList = this.synUserRev_GetFeeList(cusID, null, null,
				orgId);
		for (DataVo dataVo : dataVoList) {
			if (dataVo.getID().equals(revID)) {
				data = dataVo;
				break;
			}
		}
		return data;
	}
	
	// 得到当前房屋的费用列表信息
	public List<DataVo> sysUserRev_GetFeeListByRes(String resID, String startTime,
			String endTime, String orgId, String userId) throws Exception {
		ConditionVo conditionVo = new ConditionVo();
		conditionVo.setP0("UserRev_GetFeeListByRes");
		conditionVo.setP1(resID);
		conditionVo.setP2(startTime);
		conditionVo.setP3(endTime);
		conditionVo.setP4(orgId);
		List<DataVo> dataList = new ArrayList<DataVo>();
		Map<String, String> params = new HashMap<String, String>();

		params = ObjectToMap.objectToMapViaFields(conditionVo, true);
		SYResult sysResult = SYHttpclientCall.getSYData(params);
		List<SYSWin> list = sysResult.getUserRev_GetFeeListByRes();
		if (list != null && !list.isEmpty()) {
			SYSWin sYSWin = list.get(0);
			List<DataVo> dataVoList = sYSWin.getSyswin();
			for (DataVo dataVo : dataVoList) {
				// 9表示已经缴费
				if (!dataVo.getLockLogo().equals("9")) {
					dataVo.getCost();
					HouseUser houseUser = houseUserDAO.getHouseUser(userId);
					dataVo.setHouseUser(houseUser);
					List<Tenement> tenementList = tenementDAO
							.findTenementList(houseUser.getHouseId(), null,
									null, 0, Constants.PAGE_MAX_SIZE, null);
					dataVo.setTenement(tenementList.get(0));

					dataList.add(dataVo);
				}
			}
		}

		return dataList;
	}
	
	public DataVo synUserRev_GetFeeByRes(String resID, String orgId, String revID ,String userId)
			throws Exception {
		DataVo data = null;
		List<DataVo> dataVoList = this.sysUserRev_GetFeeListByRes(resID, null, null,
				orgId,userId);
		for (DataVo dataVo : dataVoList) {
			if (dataVo.getID().equals(revID)) {
				data = dataVo;
				break;
			}
		}
		return data;
	}

	// 按应收款进行缴费
	private List<DataVo> sysUserRev_PayFee(String cusID, String orgId,
			String deviceName, String revID, String revMoney) throws Exception {
		ConditionVo conditionVo = new ConditionVo();
		conditionVo.setP0("UserRev_PayFee");
		conditionVo.setP1(cusID);
		conditionVo.setP2(orgId);
		conditionVo.setP3(deviceName);

		List<PaymentVo> list = new ArrayList<PaymentVo>();
		PaymentVo paymentVo = new PaymentVo();
		paymentVo.setRevID(revID);
		paymentVo.setRevMoney(Double.valueOf(revMoney) / 100);
		String billNo = getBillNo();
		paymentVo.setBillNo(billNo);
		list.add(paymentVo);

		JSONObject obj = new JSONObject();
		obj.put("Syswin", list);
		conditionVo.setP7(obj.toString());

		Map<String, String> params = new HashMap<String, String>();
		List<DataVo> listb = new ArrayList<DataVo>();
		params = ObjectToMap.objectToMapViaFields(conditionVo, true);
		SYResult sysResult = SYHttpclientCall.getSYData(params);
		List<SYSWin> listv = sysResult.getUserRev_PayFee();
		if (listv != null && !listv.isEmpty()) {
			SYSWin sYSWin = listv.get(0);
			listb = sYSWin.getSyswin();
			listb.get(0).setBillNo(billNo);
		}
		return listb;
	}

	/**
	 * 微信物业缴费
	 * 
	 * @param body
	 * @param total_fee
	 * @param notify_url
	 * @param addrIp
	 * @param weixinID
	 * @param appId
	 * @param mchId
	 * @param cusID
	 * @param orgId
	 * @param paymentVo
	 * @return
	 * @throws Exception
	 */
	public ResultVo payTenementInfo(String body, String total_fee,
			String notify_url, String addrIp, String weixinID, String appId,
			String mchId, String apiKey, String cusID, String orgId,
			String revID) throws Exception {
		return sendPay(body, total_fee, notify_url, addrIp, weixinID, appId,
				mchId, apiKey, cusID, orgId, revID);
	}

	private ResultVo sendPay(String body, String total_fee, String notify_url,
			String addrIp, String weixinId, String appId, String mchId,
			String apiKey, String cusID, String orgId, String revID)
			throws Exception {
		ResultVo resultVo = new ResultVo();
		if (validatePayOrder(total_fee, cusID, orgId, revID)) {
			PayRequestVo payRequestVo = PayUnifiedOrderService.sendPay(body,
					total_fee, addrIp, weixinId, notify_url, appId, mchId,
					apiKey);
			resultVo.setSuccess(true);
			resultVo.setData(payRequestVo);
		} else {
			resultVo.setSuccess(false);
			resultVo.setMessage(ExceptionConstant
					.getExceptionMessage(ExceptionConstant.PAY_TOTAL_INCONFORMITY));
		}
		return resultVo;
	}

	/**
	 * 
	 * @param total_fee
	 *            分为单位
	 * @param cusID
	 * @param orgId
	 * @param revID
	 * @return
	 */
	private boolean validatePayOrder(String total_fee, String cusID,
			String orgId, String revID) throws Exception{
		boolean validateResult = false;
		// 单位 为元
		double orderCost = getCost(cusID, orgId, revID);
		try {
			if (total_fee != null && !"".equals(total_fee) && cusID != null
					&& !"".equals(cusID)) {
				int cost = new BigDecimal(Double.toString(orderCost)).multiply(new BigDecimal("100")).intValue();
				if (Integer.parseInt(total_fee) == cost)
					validateResult = true;
				else
					validateResult = false;
			}
		} catch (Exception e) {
			validateResult = false;
		}

		return validateResult;
	}

	private double getCost(String cusID, String orgId, String revID)
			throws Exception {
		double orderCost = 0;
		DataVo dataVo = synUserRev_GetFee(cusID, orgId, revID);
		if (dataVo != null) {
			orderCost = dataVo.getCost();
		}
		return orderCost;
	}
	
	
	/**
	 * 微信物业缴费
	 * 
	 * @param body
	 * @param total_fee
	 * @param notify_url
	 * @param addrIp
	 * @param weixinID
	 * @param appId
	 * @param mchId
	 * @param cusID
	 * @param orgId
	 * @param paymentVo
	 * @return
	 * @throws Exception
	 */
	public ResultVo payTenementInfoRes(String body, String total_fee,
			String notify_url, String addrIp, String weixinID, String appId,
			String mchId, String apiKey, String resID, String orgId,
			String revID,String userId) throws Exception {
		return sendPayRes(body, total_fee, notify_url, addrIp, weixinID, appId,
				mchId, apiKey, resID, orgId, revID, userId);
	}

	private ResultVo sendPayRes(String body, String total_fee, String notify_url,
			String addrIp, String weixinId, String appId, String mchId,
			String apiKey, String resID, String orgId, String revID ,String userId)
			throws Exception {
		ResultVo resultVo = new ResultVo();
		if (validatePayOrderRes(total_fee, resID, orgId, revID, userId)) {
			PayRequestVo payRequestVo = PayUnifiedOrderService.sendPay(body,
					total_fee, addrIp, weixinId, notify_url, appId, mchId,
					apiKey);
			resultVo.setSuccess(true);
			resultVo.setData(payRequestVo);
		} else {
			resultVo.setSuccess(false);
			resultVo.setMessage(ExceptionConstant
					.getExceptionMessage(ExceptionConstant.PAY_TOTAL_INCONFORMITY));
		}
		return resultVo;
	}

	/**
	 * 
	 * @param total_fee
	 *            分为单位
	 * @param cusID
	 * @param orgId
	 * @param revID
	 * @return
	 */
	private boolean validatePayOrderRes(String total_fee, String resID,
			String orgId, String revID ,String userId) throws Exception{
		boolean validateResult = false;
		// 单位 为元
		double orderCost = getCostRes(resID, orgId, revID, userId);
		try {
			if (total_fee != null && !"".equals(total_fee) && resID != null
					&& !"".equals(resID)) {
				int cost = new BigDecimal(Double.toString(orderCost)).multiply(new BigDecimal("100")).intValue();
				if (Integer.parseInt(total_fee) == cost)
					validateResult = true;
				else
					validateResult = false;
			}
		} catch (Exception e) {
			validateResult = false;
		}

		return validateResult;
	}

	private double getCostRes(String resID, String orgId, String revID, String userId)
			throws Exception {
		double orderCost = 0;
		DataVo dataVo = synUserRev_GetFeeByRes(resID, orgId, revID ,userId);
		if (dataVo != null) {
			orderCost = dataVo.getCost();
		}
		return orderCost;
	}

	public boolean payTenementInfoCallback(String cusID, String resID,
			String IpItemName,String repYears,String revAbstract,
			String deviceName, String orgId, String revID, String revMoney,
			String nonceStr, String appId, String mchId, String apiKey,
			String outTradeNo,String userId) throws Exception {
		return updateTenementInfo(cusID, resID, IpItemName,
				repYears,revAbstract,deviceName, orgId, revID,
				revMoney, nonceStr, appId, mchId, apiKey, outTradeNo,userId);

	}

	private boolean updateTenementInfo(String cusID, String resID,
			String IpItemName,String repYears,String revAbstract,
			String deviceName, String orgId, String revID, String revMoney,
			String nonceStr, String appId, String mchId, String apiKey,
			String outTradeNo,String userId) throws Exception {
		boolean isTrue = false;
		PayOrderQueryResult payOrderQueryResult = getPayOrderQueryResult(
				nonceStr, appId, mchId, apiKey, outTradeNo);
		// 微信入帐成功
		if ("SUCCESS".equalsIgnoreCase(payOrderQueryResult.getResult_code())
				&& "SUCCESS".equalsIgnoreCase(payOrderQueryResult
						.getTrade_state())) {
			if (validatePayOrderRes(revMoney, resID, orgId, revID, userId)) {
				List<DataVo> dataVo = sysUserRev_PayFee(cusID, orgId,
						deviceName, revID, revMoney);

				System.out.println("dataVo:" + dataVo.toString());
				// 思源缴费成功
				if (dataVo != null && dataVo.size() > 0
						&& dataVo.get(0).getState().equals("1")) {
					boolean saveStatus = saveTenementCost(cusID, resID, orgId,
							revID, revMoney, dataVo.get(0).getBillNo(),
							IpItemName,repYears,revAbstract,
							DateUtil.StringToDate(
									payOrderQueryResult.getTime_end(),
									"yyyyMMddHHmmss"),
							Constants.PAY_STATUS_SUCCESS,
							userId);
					System.out.println("思源缴费成功,保存状态:" + saveStatus);
					isTrue = true;
				} else {
					// 思源缴费失败 录入微信成功系统录入失败状态
					System.out.println("思源缴费失败");
					boolean saveStatus = saveTenementCost(cusID, resID, orgId,
							revID, revMoney, dataVo.get(0).getBillNo(), IpItemName,
							repYears,revAbstract,
							DateUtil.StringToDate(
									payOrderQueryResult.getTime_end(),
									"yyyyMMddHHmmss"),
							Constants.PAY_STATUS_SYS_FAIL,
							userId);
					isTrue = true;
				}

			} else {
				// 思源缴费失败 录入微信成功系统录入失败状态
				System.out.println("思源缴费验证失败");
				boolean saveStatus = saveTenementCost(cusID, resID, orgId,
						revID, revMoney, null,IpItemName,
						repYears,revAbstract, DateUtil.StringToDate(
								payOrderQueryResult.getTime_end(),
								"yyyyMMddHHmmss"),
						Constants.PAY_STATUS_SYS_FAIL,
						userId);
				isTrue = true;
			}

		} else {
			System.out.println("微信缴费失败");
			isTrue = false;
		}
		return isTrue;
	}

	/**
	 * 从微信那儿查询订单
	 * 
	 * @param nonceStr
	 * @param sign
	 * @param appId
	 * @param mchId
	 * @param outTradeNo
	 * @return
	 * @throws Exception
	 */
	private PayOrderQueryResult getPayOrderQueryResult(String nonceStr,
			String appId, String mchId, String apiKey, String outTradeNo)
			throws Exception {
		PayOrderQueryResult payOrderQueryResult = PayUnifiedOrderService
				.getPayOrderQueryResult(nonceStr, appId, mchId, apiKey,
						outTradeNo);

		return payOrderQueryResult;
	}

	private static String getBillNo() {
		DateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
		String dateStr = sdf.format(new Date());
		return "HRNO" + dateStr;
	}

	private boolean saveTenementCost(String cusID, String resId, String orgId,
			String revID, String revMoney, String billNo,String IpItemName,
			String repYears,String revAbstract, Date chargeTime,
			int status,String userId) throws Exception {
		boolean isTrue = false;
		try {
			TenementCost tenementCost = new TenementCost();
			tenementCost.setBillNo(billNo);
			tenementCost.setIpItemName(IpItemName);
			tenementCost.setRepYears(repYears);
			tenementCost.setRevAbstract(repYears);
			
			
			tenementCost.setCost(Double.valueOf(revMoney) / 100);
			tenementCost.setRevID(revID);
			tenementCost.setStatus(status);
			tenementCost.setChargeTime(chargeTime);

			HouseUser houseUser = houseUserDAO.getHouseUser(userId);
			tenementCost.setHouseUser(houseUser);
			tenementCost.setHrHouses(houseUser.getHrHouses());

			List<Tenement> tenementList = tenementDAO.findTenementList(
					houseUser.getHrHouses().getId(), null, null, 0,
					Constants.PAGE_MAX_SIZE, null);
			
			System.out.println("*******************houseUser.getHrHouses().getId():"+houseUser.getHrHouses().getId());
			System.out.println("*******************tenementList:"+tenementList);
			tenementCost.setTenement(tenementList.get(0));

			tenementCostDAO.save(tenementCost);
			isTrue = true;
		} catch (Exception e) {
			isTrue = false;
			e.printStackTrace();
		}
		return isTrue;
	}
}
